<template>
  <div class="max-w-4xl mx-auto p-4">
    <a-card>
      <a-typography-title :level="2">颜色工具</a-typography-title>
      
      <a-tabs v-model:activeKey="activeTab">
        <!-- 颜色拾取器 -->
        <a-tab-pane key="picker" tab="颜色拾取器">
          <div class="mb-4">
            <a-upload
              v-model:fileList="fileList"
              :beforeUpload="handleBeforeUpload"
              :showUploadList="false"
              accept="image/*"
            >
              <div class="border-2 border-dashed border-gray-300 p-4 text-center hover:border-primary">
                <div class="relative">
                  <img v-if="imageUrl" :src="imageUrl" class="max-w-full max-h-[400px] mx-auto" @click="handleImageClick" />
                  <div v-else class="text-gray-500">
                    <upload-outlined />
                    <div>点击或拖拽图片到此区域</div>
                  </div>
                  <div v-if="pickedColor" class="absolute top-2 right-2 p-2 bg-white rounded shadow">
                    <div class="flex items-center gap-2">
                      <div class="w-6 h-6 rounded" :style="{ backgroundColor: pickedColor }" />
                      <span>{{ pickedColor }}</span>
                      <a-button type="link" size="small" @click="copyColor">
                        <template #icon><copy-outlined /></template>
                      </a-button>
                    </div>
                  </div>
                </div>
              </div>
            </a-upload>
          </div>
          <div v-if="imageUrl" class="text-center text-gray-500">
            点击图片任意位置获取颜色
          </div>
        </a-tab-pane>

        <!-- 颜色值转换器 -->
        <a-tab-pane key="converter" tab="颜色值转换器">
          <a-form layout="vertical">
            <a-form-item label="选择颜色">
              <div class="flex items-center gap-4">
                <a-input v-model:value="colorInput" placeholder="#FF0000 或 rgb(255,0,0)" />
                <a-input type="color" v-model:value="colorValue" class="w-20" />
              </div>
            </a-form-item>

            <a-divider>转换结果</a-divider>

            <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
              <a-card size="small">
                <template #title>HEX</template>
                <div class="flex justify-between items-center">
                  <span>{{ colorFormats.hex }}</span>
                  <a-button type="link" size="small" @click="copyFormat('hex')">
                    <template #icon><copy-outlined /></template>
                  </a-button>
                </div>
              </a-card>

              <a-card size="small">
                <template #title>RGB</template>
                <div class="flex justify-between items-center">
                  <span>{{ colorFormats.rgb }}</span>
                  <a-button type="link" size="small" @click="copyFormat('rgb')">
                    <template #icon><copy-outlined /></template>
                  </a-button>
                </div>
              </a-card>

              <a-card size="small">
                <template #title>HSL</template>
                <div class="flex justify-between items-center">
                  <span>{{ colorFormats.hsl }}</span>
                  <a-button type="link" size="small" @click="copyFormat('hsl')">
                    <template #icon><copy-outlined /></template>
                  </a-button>
                </div>
              </a-card>

              <a-card size="small">
                <template #title>HSV</template>
                <div class="flex justify-between items-center">
                  <span>{{ colorFormats.hsv }}</span>
                  <a-button type="link" size="small" @click="copyFormat('hsv')">
                    <template #icon><copy-outlined /></template>
                  </a-button>
                </div>
              </a-card>
            </div>

            <a-divider>预览</a-divider>
            
            <div class="h-20 rounded" :style="{ backgroundColor: colorValue }" />
          </a-form>
        </a-tab-pane>
      </a-tabs>
    </a-card>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, watch } from 'vue';
import { message } from 'ant-design-vue';
import { UploadOutlined, CopyOutlined } from '@ant-design/icons-vue';
import type { UploadProps } from 'ant-design-vue';

// 标签页
const activeTab = ref('picker');

// 颜色拾取器
const fileList = ref<any[]>([]);
const imageUrl = ref('');
const pickedColor = ref('');

// 颜色值转换器
const colorInput = ref('');
const colorValue = ref('#FF0000');

// 处理图片上传
const handleBeforeUpload: UploadProps['beforeUpload'] = (file) => {
  const isImage = file.type.startsWith('image/');
  if (!isImage) {
    message.error('只能上传图片文件！');
    return false;
  }

  const reader = new FileReader();
  reader.onload = (e) => {
    if (e.target?.result) {
      imageUrl.value = e.target.result as string;
    }
  };
  reader.readAsDataURL(file);

  return false;
};

// 处理图片点击，获取颜色
const handleImageClick = (e: MouseEvent) => {
  const img = e.target as HTMLImageElement;
  const canvas = document.createElement('canvas');
  const ctx = canvas.getContext('2d');
  if (!ctx) return;

  canvas.width = img.naturalWidth;
  canvas.height = img.naturalHeight;
  ctx.drawImage(img, 0, 0);

  const rect = img.getBoundingClientRect();
  const x = e.clientX - rect.left;
  const y = e.clientY - rect.top;
  
  // 计算实际图片坐标
  const scaleX = img.naturalWidth / img.width;
  const scaleY = img.naturalHeight / img.height;
  const actualX = Math.floor(x * scaleX);
  const actualY = Math.floor(y * scaleY);

  const pixel = ctx.getImageData(actualX, actualY, 1, 1).data;
  pickedColor.value = `rgb(${pixel[0]}, ${pixel[1]}, ${pixel[2]})`;
};

// 复制颜色值
const copyColor = () => {
  if (pickedColor.value) {
    navigator.clipboard.writeText(pickedColor.value);
    message.success('颜色值已复制到剪贴板');
  }
};

// 颜色格式转换
const parseColor = (color: string) => {
  // 创建一个临时元素来使用浏览器的颜色解析
  const temp = document.createElement('div');
  temp.style.color = color;
  document.body.appendChild(temp);
  const computed = getComputedStyle(temp).color;
  document.body.removeChild(temp);
  return computed;
};

// RGB 转 HEX
const rgbToHex = (r: number, g: number, b: number) => {
  return '#' + [r, g, b].map(x => {
    const hex = x.toString(16);
    return hex.length === 1 ? '0' + hex : hex;
  }).join('');
};

// RGB 转 HSL
const rgbToHsl = (r: number, g: number, b: number) => {
  r /= 255;
  g /= 255;
  b /= 255;
  const max = Math.max(r, g, b);
  const min = Math.min(r, g, b);
  let h = 0, s, l = (max + min) / 2;

  if (max === min) {
    h = s = 0;
  } else {
    const d = max - min;
    s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
    switch (max) {
      case r: h = (g - b) / d + (g < b ? 6 : 0); break;
      case g: h = (b - r) / d + 2; break;
      case b: h = (r - g) / d + 4; break;
    }
    h /= 6;
  }

  return [
    Math.round(h * 360),
    Math.round(s * 100),
    Math.round(l * 100)
  ];
};

// RGB 转 HSV
const rgbToHsv = (r: number, g: number, b: number) => {
  r /= 255;
  g /= 255;
  b /= 255;
  const max = Math.max(r, g, b);
  const min = Math.min(r, g, b);
  let h = 0, s, v = max;

  const d = max - min;
  s = max === 0 ? 0 : d / max;

  if (max === min) {
    h = 0;
  } else {
    switch (max) {
      case r: h = (g - b) / d + (g < b ? 6 : 0); break;
      case g: h = (b - r) / d + 2; break;
      case b: h = (r - g) / d + 4; break;
    }
    h /= 6;
  }

  return [
    Math.round(h * 360),
    Math.round(s * 100),
    Math.round(v * 100)
  ];
};

// 颜色格式
const colorFormats = computed(() => {
  try {
    const color = parseColor(colorInput.value || colorValue.value);
    const match = color.match(/rgb\((\d+),\s*(\d+),\s*(\d+)\)/);
    if (match) {
      const [_, r, g, b] = match.map(Number);
      const hex = rgbToHex(r, g, b);
      const [h, s, l] = rgbToHsl(r, g, b);
      const [hv, sv, v] = rgbToHsv(r, g, b);
      
      return {
        hex,
        rgb: `rgb(${r}, ${g}, ${b})`,
        hsl: `hsl(${h}, ${s}%, ${l}%)`,
        hsv: `hsv(${hv}, ${sv}%, ${v}%)`
      };
    }
  } catch (e) {
    console.error('颜色解析错误:', e);
  }
  
  return {
    hex: '#000000',
    rgb: 'rgb(0, 0, 0)',
    hsl: 'hsl(0, 0%, 0%)',
    hsv: 'hsv(0, 0%, 0%)'
  };
});

// 复制格式化的颜色值
const copyFormat = (format: keyof typeof colorFormats.value) => {
  const value = colorFormats.value[format];
  navigator.clipboard.writeText(value);
  message.success(`${format.toUpperCase()} 格式的颜色值已复制到剪贴板`);
};

// 监听颜色输入变化
watch(colorInput, (newValue) => {
  try {
    const color = parseColor(newValue);
    if (color !== 'rgb(0, 0, 0)' || newValue.toLowerCase() === 'black') {
      colorValue.value = color;
    }
  } catch (e) {
    console.error('颜色解析错误:', e);
  }
});
</script>

<style scoped>
.ant-upload {
  width: 100%;
}

:deep(.ant-input[type="color"]) {
  padding: 0;
  cursor: pointer;
}

:deep(.ant-card-body) {
  padding: 24px;
}
</style> 